package com.lightningtrade.service.impl;

import com.lightningtrade.domain.SysUser;
import com.lightningtrade.mapper.SysLoginMapper;
import com.lightningtrade.mapper.SysUserMapper;
import com.lightningtrade.security.UserDetails;
import com.lightningtrade.service.SysLoginService;
import com.lightningtrade.service.SysUserService;
import com.lightningtrade.util.AjaxResult;
import com.lightningtrade.util.JwtTokenUtil;
import com.lightningtrade.util.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class SysLoginServiceImpl implements SysLoginService {

    @Value("${token.expireTime:30}") // 默认值 30 分钟
    private long defaultExpireTime;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private SysLoginMapper loginMapper;

    @Autowired
    private SysUserService userService;

    @Override
    public AjaxResult login(SysUser user) {
        System.out.println("开始身份认证...\n");
        /**
         * 1. 生成一个authenticationToken
         * 2. 用authenticationManager进行用户认证
         * 3. 如果认证没通过，给出对应提示
         * 4. 如果认证通过了，用uid生成一个jwt
         * 5. 把完整的用户信息存入Redis，key为login+uid, value为UserDetails
         * 6. 返回jwt
         */
        //生成一个authenticationToken ---认证令牌（正在请求的，未授权的）
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
        System.out.println("SysLoginService-生成authenticationToken成功 :\n\t"+authenticationToken + "\n");

        //用 AuthenticationManager ---认证管理器， 进行用户认证， 生成一个 authorization ---授权令牌
        Authentication authorization = null;
        try {
            authorization = authenticationManager.authenticate(authenticationToken);

        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("用户名或密码错误");
        }

        System.out.println("SysLoginService-认证完成:\n\t"+authorization + "\n");


        //如果认证没通过，给出对应提示
        if(Objects.isNull(authorization)){
            System.out.println("SysLoginService-认证失败\n");
            throw new RuntimeException("用户名或密码错误");
        }

        //如果认证通过了，用uid生成一个jwt
        UserDetails loginUserDetails = (UserDetails) authorization.getPrincipal();
        String userid = loginUserDetails.getUid().toString();
        String jwt = jwtTokenUtil.generateJWT(userid);
        System.out.println("SysLoginService-生成jwt:\n\t"+jwt + "\n");

        //把用户信息存入Redis，key为login+uid
        redisCache.setCacheObject("login:"+userid, loginUserDetails, defaultExpireTime, TimeUnit.MINUTES);

        System.out.println("SysLoginService-存储登录信息到Redis\n");

        return AjaxResult.success("登录成功", jwt);
    }

    @Override
    public boolean logout() {
        // 从SecurityContextHolder中获取用户信息
        UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        UserDetails loginUser = (UserDetails) authenticationToken.getPrincipal();
        String userid = loginUser.getUid().toString();

        // 从redis中删除用户信息
        redisCache.deleteObject("login:" + userid);
        return true;
    }

    @Override
    public AjaxResult register(SysUser user) {

        // 1. 判断用户名是否存在
        if (loginMapper.getUserByUsername(user.getUsername()) != null) {
            return AjaxResult.error("用户名已存在");
        }

        // 2. 判断手机号是否存在
        if (loginMapper.getUserByPhone(user.getPhone()) != null) {
            return AjaxResult.error("手机号已注册");
        }

//        // 3. 判断邮箱是否存在
//        if (loginMapper.getUserByEmail(user.getEmail()) != null) {
//            return AjaxResult.error("邮箱已注册");
//        }

        // 4. 密码加密
        user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));

        // 5. 注册用户，插入用户信息
        Integer rows = loginMapper.insertUser(user);
        if (rows > 0) {
            return AjaxResult.success("注册成功",null);
        }
        return AjaxResult.error("注册失败");
    }

    @Override
    public SysUser getLoginUser() {
        // 从SecurityContextHolder中获取用户信息
        UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        UserDetails loginUser = (UserDetails) authenticationToken.getPrincipal();
        return userService.getUserByUid(loginUser.getUid().toString());
    }
}
